package com.hardson.toolkit.interfaces.consts;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public interface IEnumBase<T> extends Serializable {

    T getCode();

    String getName();

    default T getValue() {
        return this.getCode();
    }

    default boolean matchCode(final T code) {
        return this.getCode().equals(code);
    }

    default boolean unMatchCode(final T code) {
        return !this.matchCode(code);
    }

    default boolean matchName(final String name) {
        return this.getName().equals(name);
    }
    static <T> String getNameByCode(final IEnumBase<T>[] enumBases, final T code) {
        return getNameByCode(enumBases, code, "未知");
    }

    static <T> String getNameByCode(final IEnumBase<T>[] enumBases, final T code, String notFoundName) {
        IEnumBase<T> base = fromCode(enumBases, code);
        return base == null ? notFoundName : base.getName();
    }

    @SuppressWarnings("unchecked")
    static <T, E> E fromCode(final IEnumBase<T>[] enumBases, final T code) {
        return (E) Stream.of(enumBases).filter(e -> e.matchCode(code)).findAny().orElse(null);
    }

    @SuppressWarnings("unchecked")
    static <T, E> E fromName(final IEnumBase<T>[] enumBases, final String name) {
        return (E) Stream.of(enumBases).filter(e -> e.matchName(name)).findAny().orElse(null);
    }

    static <T> T getCodeByName(final IEnumBase<T>[] enumBases, final String name) {
        IEnumBase<T> base = fromName(enumBases, name);
        return base == null ? null : base.getCode();
    }
    @SuppressWarnings("unchecked")
    static <T, E> List<E> toList(final IEnumBase<T>[] enumBases,
                                 final IEnumBase<?>... filterElement) {
        List<IEnumBase<?>> filterList = Arrays.asList(filterElement);
        return (List<E>) Stream.of(enumBases)//
                .filter(e -> !filterList.contains(e))//
                .collect(Collectors.toList());
    }

}
